#!/usr/bin/env python
#
# Copyright (C) 2011 Clement Lorteau <clem@lorteau.fr>	
#		
# This file is part of QuickScreenShots.		
# 	
# This program is free software; you can redistribute it and/or modify	
# it under the terms of the GNU General Public License as published by		
# the Free Software Foundation; version 3.	
# 	
# This program is distributed in the hope that it will be useful,		
# but WITHOUT ANY WARRANTY; without even the implied warranty of		
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the		
# GNU General Public License for more details.		
# 		
# You should have received a copy of the GNU General Public License		
# along with this program; if not, write to the Free Software		
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

"""Source: http://www.py2exe.org/index.cgi/BetterCompression"""

from distutils.core import setup
import py2exe
import sys
import os
import time
import shutil
from __init__ import __version__

sys.argv.append('py2exe')

# manifest is to get windows visual styles working
# pythonhaven.wordpress.com/2009/10/07/how-to-get-xp-styles-on-wxpython-apps-made-with-py2exe
manifest = """
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
     type='win32'
     name='Microsoft.VC90.CRT'
     version='9.0.21022.8'
     processorArchitecture='*'
     publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
         type="win32"
         name="Microsoft.Windows.Common-Controls"
         version="6.0.0.0"
         processorArchitecture="*"
         publicKeyToken="6595b64144ccf1df"
         language="*" />
    </dependentAssembly>
  </dependency>
</assembly>
"""
RT_MANIFEST = 24

quickscreenshots = dict(
    script = "qss.py",
    icon_resources = [(1, 'resources/snapshot.ico')],
    other_resources = [(RT_MANIFEST, 1, manifest)],
    dest_base = r"quickscreenshots")

zipfile = "lib/sharedlib"

options = {"py2exe": {"compressed": 1,
                      "optimize": 2,
                      "dll_excludes": "MSVCP90.dll, psvince.dll"
                     }}

class InnoScript:
    def __init__(self,
                 name,
                 lib_dir,
                 dist_dir,
                 windows_exe_files = [],
                 lib_files = [],
                 version = "1.0"):
        self.lib_dir = lib_dir
        self.dist_dir = dist_dir
        if not self.dist_dir[-1] in "\\/":
            self.dist_dir += "\\"
        self.name = name
        self.version = version
        self.windows_exe_files = [self.chop(p) for p in windows_exe_files]
        self.lib_files = [self.chop(p) for p in lib_files]

    def chop(self, pathname):
        assert pathname.startswith(self.dist_dir)
        return pathname[len(self.dist_dir):]
    
    def create(self, pathname="dist\\quickscreenshots.iss"):
        self.pathname = pathname
        ofi = self.file = open(pathname, "w")
        print >> ofi, "; WARNING: This script has been created by py2exe. Changes to this script"
        print >> ofi, "; will be overwritten the next time py2exe is run!"
        print >> ofi, r"[Setup]"
        print >> ofi, r"AppName=%s" % self.name
        print >> ofi, r"AppVerName=%s %s" % (self.name, self.version)
        print >> ofi, r"DefaultDirName={pf}\%s" % self.name
        print >> ofi, r"DefaultGroupName=%s" % self.name
        print >> ofi, r"Compression=lzma/max"
        print >> ofi

        print >> ofi, r"[Files]"
        print >> ofi, r"Source: ../psvince.dll; Flags: dontcopy" #used to detect if a module is running during setup
        for path in self.windows_exe_files + self.lib_files:
            print >> ofi, r'Source: "%s"; DestDir: "{app}\%s"; Flags: ignoreversion' % (path, os.path.dirname(path))
        print >> ofi

        print >> ofi, r"[Icons]"
        for path in self.windows_exe_files:
            print >> ofi, r'Name: "{group}\%s"; Filename: "{app}\%s"' % \
                  (self.name, path)
        print >> ofi, 'Name: "{group}\Uninstall %s"; Filename: "{uninstallexe}"' % self.name
        
        #Offer to start quickscreenshots at end of installation
        print >> ofi, r"[Run]"
        print >> ofi, r'Filename: "{app}\quickscreenshots.exe"; Description: "{cm:LaunchProgram,%s}"; Flags: nowait postinstall skipifsilent' % self.name

        
        #Don't install if quickscreenshots is already running
        # print >> ofi, r"[Run]"
        # print >> ofi, r"Filename: taskkill; Parameters: /f /im quickscreenshots.exe; WorkingDir: {sys}; Flags: runhidden skipifdoesntexist"
        print >> ofi, """[Code]
function IsModuleLoaded(modulename: AnsiString ): Boolean;
external 'IsModuleLoaded@files:psvince.dll stdcall';

function InitializeSetup(): Boolean;
begin

   if(Not IsModuleLoaded('quickscreenshots.exe')) then
   begin
       Result := true;
   end
   else
   begin
       MsgBox('QuickScreenShots is already running. Please close it and re-start the installation program.', mbInformation, MB_OK);
       Result := false;
   end

end;"""
            
    def compile(self):
        try:
            import ctypes
        except ImportError:
            try:
                import win32api
            except ImportError:
                import os
                os.startfile(self.pathname)
            else:
                win32api.ShellExecute(0, "compile",
                                                self.pathname,
                                                None,
                                                None,
                                                0)
        else:
            res = ctypes.windll.shell32.ShellExecuteA(0, "compile",
                                                      self.pathname,
                                                      None,
                                                      None,
                                                      0)
            if res < 32:
                raise RuntimeError, "ShellExecute failed, error %d" % res

from py2exe.build_exe import py2exe

class build_installer(py2exe):
    # Load our own boot_common boot script
    def get_boot_script(self, boot_type):
        if boot_type == 'common':
            return "boot_common.py"
        else:
            return py2exe.get_boot_script(self, boot_type)
    
    # This class first builds the exe file(s), then creates a Windows installer.
    # You need InnoSetup for it.
    def run(self):
        # First, let py2exe do it's work.
        py2exe.run(self)

        lib_dir = self.lib_dir
        dist_dir = self.dist_dir
        
        # create the Installer, using the files py2exe has created.
        script = InnoScript("QuickScreenShots",
                            lib_dir,
                            dist_dir,
                            self.windows_exe_files,
                            self.lib_files,
                            version=__version__)
        print "*** creating the inno setup script***"
        script.create()
        print "*** compiling the inno setup script***"
        script.compile()
        # Note: By default the final setup.exe will be in an Output subdirectory.

mfcdir = 'C:\\Python27\\Lib\\site-packages\\pythonwin\\'
mfcfiles = [mfcdir+"mfc90.dll",
            mfcdir+"mfc90u.dll",
            mfcdir+"mfcm90.dll",
            mfcdir+"mfcm90u.dll",
            mfcdir+"Microsoft.VC90.MFC.manifest"]
resources = []
for f in os.listdir('resources'):
    resources.append('resources/'+f)
        
setup(
    options = options,
    zipfile = zipfile,
    windows = [quickscreenshots],
    data_files = [("Microsoft.VC90.MFC", mfcfiles),
                  ("resources", resources)],
    cmdclass = {"py2exe": build_installer},
    )

print 'Waiting 30 seconds before cleaning up...'
time.sleep(30)
dest = '../QuickScreenShots-%s-setup.exe' % __version__
if os.path.exists(dest):
    os.unlink(dest)
shutil.move('dist/Output/setup.exe', dest)
shutil.rmtree('dist')
shutil.rmtree('build')